(function (global) {	// BEGIN CLOSURE

    var Joint = global.Joint,
     Element = Joint.dia.Element,
     point = Joint.point;

    /**
    * @name Joint.dia.org
    * @namespace Holds functionality related to Org-charts.
    */
    var org = Joint.dia.org = {};

    /**
    * Predefined arrow. You are free to use this arrow as the option parameter to joint method.
    * @name arrow
    * @memberOf Joint.dia.org
    * @example
    * var arrow = Joint.dia.org.arrow;
    */
    org.arrow = {
        startArrow: { type: 'none' },
        endArrow: { type: 'none' },
        attrs: { 'stroke-dasharray': '1', 'stroke-width': 2, stroke: 'black' }
    };


    /**
    * Organizational chart member.
    * @methodOf Joint.dia.org
    */
    org.Member = Element.extend({
        object: 'Member',
        module: 'org',
        init: function (properties) {
            var p = Joint.DeepSupplement(this.properties, properties, {
                attrs: { fill: 'white', stroke: '#007e09', 'stroke-width': 1 },
                name: '',
                designation: '',
                company: '',
                indirectReporting: '',
                grade: '',
                workLevel: '',
                nameAttrs: { 'font-weight': 'bold', cursor: 'pointer', stroke: 'blue', 'stroke-width': 0.3, 'title': 'EPF No. : Employee Name' },
                designationAttrs: { 'font-weight': 'normal', 'title': 'Designation Name' },
                companyAttrs: { 'font-weight': 'bold', 'title': 'Company Name' },
                indirectReportingAttrs: { 'font-weight': 'normal', 'font-style': 'italic', 'title': 'Indirect Reporting' },
                indirectTextAttrs: { 'stroke': 'red', 'stroke-width': 0.3 },
                gradeAttrs: { 'font-weight': 'bold', 'title': 'Grade Name' },
                workLevelAttrs: { 'font-weight': 'bold', 'title': 'Work Level Name' },
                swimlaneAttrs: { 'stroke-width': 0, 'stroke': 'white' },
                labelOffsetY: 10,
                avatarHeight: 100,
                radius: 4,
                shadow: true,
                empURL: '',
                designationURL: '',
                companyURL: '',
                avatar: '',
                padding: 3,
                compactView: false
            });
            this.setWrapper(this.paper.rect(p.rect.x, p.rect.y, p.rect.width, p.rect.height, p.radius).attr(p.attrs));
            if (p.avatar && !p.compactView) {
                //this.addInner(this.paper.image(p.avatar, p.rect.x + p.padding, p.rect.y + p.padding, p.rect.height - 2 * p.padding, p.rect.height - 2 * p.padding));
                this.addInner(this.paper.image(p.avatar, p.rect.x + p.padding, p.rect.y + p.padding, p.avatarHeight - 2 * p.padding, p.avatarHeight - 2 * p.padding));
                p.labelOffsetX = p.avatarHeight;
            } else {
                p.labelOffsetX = 10;
            }
            if (p.name != null && p.name != '') {
                var nameElement = this.getNameElement();
                this.addInner(nameElement[0]);
                this.addInner(nameElement[1]);      // swimlane
            }
            if (!p.compactView) {
                this.addInner(this.getDesignationElement());
                this.addInner(this.getCompanyElement());
                var indirectReportingElement = this.getIndirectReportingElement();
                this.addInner(indirectReportingElement[0]);
                this.addInner(indirectReportingElement[1]);
            }
            if (!p.compactView) {
                this.addInner(this.getGradeElement(6));
                this.addInner(this.getWorkLevelElement(8));
            } else {
                this.addInner(this.getGradeElement(2));
                this.addInner(this.getWorkLevelElement(4));
            }
        },
        getNameElement: function () {
            var p = this.properties,
	        bb = this.wrapper.getBBox(),
	        t = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, p.name).attr(p.nameAttrs).click(function (e) { window.open(p.empURL); }),
	        tbb = t.getBBox();
            t.translate(bb.x - tbb.x + p.labelOffsetX, bb.y - tbb.y + tbb.height);
            tbb = t.getBBox();
            var l = this.paper.path(['M', tbb.x, tbb.y + tbb.height + p.padding,
                                 'L', tbb.x + tbb.width, tbb.y + tbb.height + p.padding].join(' '));
            return [t, l];
        },
        getDesignationElement: function () {
            var p = this.properties,
	        bb = this.wrapper.getBBox(),
	        t = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, p.designation).attr(p.designationAttrs || {}).click(function (e) { window.open(p.designationURL); }),
	        tbb = t.getBBox();
            t.translate(bb.x - tbb.x + p.labelOffsetX, bb.y - tbb.y + tbb.height * 2 + p.labelOffsetY);
            return t;
        },
        getCompanyElement: function () {
            var p = this.properties,
	        bb = this.wrapper.getBBox(),
	        t = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, p.company).attr(p.companyAttrs).click(function (e) { window.open(p.companyURL); }),
	        tbb = t.getBBox();
            t.translate(bb.x - tbb.x + p.labelOffsetX, bb.y - tbb.y + tbb.height * 3 + p.labelOffsetY);
            return t;
        },
        getIndirectReportingElement: function () {
            var indirectText = (this.properties.indirectReporting == null || this.properties.indirectReporting == '') ? '' : 'indirect';

            var p = this.properties,
	        bb = this.wrapper.getBBox(),
	        t1 = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, indirectText).attr(p.indirectTextAttrs),
	        tbb1 = t1.getBBox();
            t1.translate(bb.x - tbb1.x + p.labelOffsetX, bb.y - tbb1.y + tbb1.height * 4 + p.labelOffsetY);

            var t2 = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, p.indirectReporting).attr(p.indirectReportingAttrs || {}),
	        tbb2 = t2.getBBox();
            t2.translate(bb.x - tbb2.x + p.labelOffsetX, bb.y - tbb2.y + tbb2.height * 5 + p.labelOffsetY);
            return [t1, t2];
        },
        getGradeElement: function (yFactor) {
            var p = this.properties,
	        bb = this.wrapper.getBBox(),
	        t = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, p.grade).attr(p.gradeAttrs || {}),
	        tbb = t.getBBox();
            t.translate(bb.x - tbb.x + p.labelOffsetX, bb.y - tbb.y + tbb.height * yFactor + p.labelOffsetY);
            return t;
        },
        getWorkLevelElement: function (yFactor) {
            var p = this.properties,
	        bb = this.wrapper.getBBox(),
	        t = this.paper.text(bb.x + bb.width / 2, bb.y + bb.height / 2, p.workLevel).attr(p.workLevelAttrs || {}),
	        tbb = t.getBBox();
            t.translate(bb.x - tbb.x + p.labelOffsetX, bb.y - tbb.y + tbb.height * yFactor + p.labelOffsetY);
            return t;
        }
    });

})(this);          	// END CLOSURE
